// Package config 提供配置管理功能
// 支持从配置文件、环境变量和命令行参数加载配置
package config

import (
	"fmt"
	"os"
	"path/filepath"

	"gopkg.in/yaml.v3"
)

// Config 配置结构体，包含所有可配置的参数
type Config struct {
	// API配置
	APIKey  string `yaml:"api_key" json:"api_key"`
	BaseURL string `yaml:"base_url" json:"base_url"`
	Model   string `yaml:"model" json:"model"`

	// 搜索配置
	SerpApiKey string `yaml:"serpapi_key" json:"serpapi_key"`

	// 执行配置
	MaxIterations    int `yaml:"max_iterations" json:"max_iterations"`
	MaxHistory       int `yaml:"max_history" json:"max_history"`
	CommandTimeout   int `yaml:"command_timeout" json:"command_timeout"`
	ReasoningTimeout int `yaml:"reasoning_timeout" json:"reasoning_timeout"`

	// 行为配置
	SkipConfirm bool `yaml:"skip_confirm" json:"skip_confirm"`

	// 文件路径
	ConfigFile string `yaml:"-" json:"-"` // 不序列化到YAML中
}

// DefaultConfig 返回默认配置
func DefaultConfig() *Config {
	return &Config{
		APIKey:           "",
		BaseURL:          "https://api.deepseek.com/v1",
		Model:            "deepseek-chat",
		SerpApiKey:       "",
		MaxIterations:    50,
		MaxHistory:       10,
		CommandTimeout:   300,
		ReasoningTimeout: 120,
		SkipConfirm:      false,
		ConfigFile:       "",
	}
}

// GetConfigPath 获取配置文件路径
// 优先级：指定路径 > $HOME/.aish/conf.yml
func GetConfigPath(specifiedPath string) (string, error) {
	if specifiedPath != "" {
		return specifiedPath, nil
	}

	homeDir, err := os.UserHomeDir()
	if err != nil {
		return "", fmt.Errorf("无法获取用户主目录: %v", err)
	}

	configDir := filepath.Join(homeDir, ".aish")
	configFile := filepath.Join(configDir, "conf.yml")

	return configFile, nil
}

// EnsureConfigDir 确保配置目录存在
func EnsureConfigDir(configPath string) error {
	configDir := filepath.Dir(configPath)

	if _, err := os.Stat(configDir); os.IsNotExist(err) {
		if err := os.MkdirAll(configDir, 0755); err != nil {
			return fmt.Errorf("创建配置目录失败 %s: %v", configDir, err)
		}
	}

	return nil
}

// LoadConfig 加载配置文件
func LoadConfig(configPath string) (*Config, error) {
	// 从默认配置开始
	config := DefaultConfig()

	// 获取实际的配置文件路径
	actualPath, err := GetConfigPath(configPath)
	if err != nil {
		return config, err
	}

	config.ConfigFile = actualPath

	// 检查配置文件是否存在
	if _, err := os.Stat(actualPath); os.IsNotExist(err) {
		// 配置文件不存在，返回默认配置
		return config, nil
	}

	// 读取配置文件
	data, err := os.ReadFile(actualPath)
	if err != nil {
		return config, fmt.Errorf("读取配置文件失败 %s: %v", actualPath, err)
	}

	// 解析YAML
	if err := yaml.Unmarshal(data, config); err != nil {
		return config, fmt.Errorf("解析配置文件失败 %s: %v", actualPath, err)
	}

	// 设置实际使用的配置文件路径
	config.ConfigFile = actualPath

	return config, nil
}

// SaveConfig 保存配置到文件
func (c *Config) SaveConfig(configPath string) error {
	// 获取实际的配置文件路径
	actualPath, err := GetConfigPath(configPath)
	if err != nil {
		return err
	}

	// 确保配置目录存在
	if err := EnsureConfigDir(actualPath); err != nil {
		return err
	}

	// 序列化配置为YAML
	data, err := yaml.Marshal(c)
	if err != nil {
		return fmt.Errorf("序列化配置失败: %v", err)
	}

	// 写入文件
	if err := os.WriteFile(actualPath, data, 0644); err != nil {
		return fmt.Errorf("写入配置文件失败 %s: %v", actualPath, err)
	}

	return nil
}

// MergeWithEnvVars 从环境变量覆盖配置
func (c *Config) MergeWithEnvVars() {
	if val := os.Getenv("OPENAI_API_KEY"); val != "" {
		c.APIKey = val
	}
	if val := os.Getenv("OPENAI_BASE_URL"); val != "" {
		c.BaseURL = val
	}
	if val := os.Getenv("OPENAI_MODEL"); val != "" {
		c.Model = val
	}
	if val := os.Getenv("SERPAPI_KEY"); val != "" {
		c.SerpApiKey = val
	}
	if val := os.Getenv("AISH_SKIP_CONFIRM"); val == "true" {
		c.SkipConfirm = true
	}
}

// Validate 验证配置的有效性
func (c *Config) Validate() error {
	if c.APIKey == "" {
		return fmt.Errorf("API密钥未设置，请在配置文件中设置 api_key 或使用环境变量 OPENAI_API_KEY")
	}

	if c.BaseURL == "" {
		return fmt.Errorf("API基础URL不能为空")
	}

	if c.Model == "" {
		return fmt.Errorf("AI模型不能为空")
	}

	if c.MaxIterations <= 0 {
		return fmt.Errorf("最大循环次数必须大于0")
	}

	if c.MaxHistory <= 0 {
		return fmt.Errorf("最大历史记录数量必须大于0")
	}

	if c.CommandTimeout <= 0 {
		return fmt.Errorf("命令执行超时时间必须大于0")
	}

	if c.ReasoningTimeout <= 0 {
		return fmt.Errorf("推理超时时间必须大于0")
	}

	return nil
}

// GetDisplayInfo 获取配置信息用于显示
func (c *Config) GetDisplayInfo() map[string]interface{} {
	return map[string]interface{}{
		"配置文件":   c.ConfigFile,
		"API地址":  c.BaseURL,
		"AI模型":   c.Model,
		"最大循环次数": c.MaxIterations,
		"历史记录数量": c.MaxHistory,
		"命令超时":   fmt.Sprintf("%ds", c.CommandTimeout),
		"推理超时":   fmt.Sprintf("%ds", c.ReasoningTimeout),
		"跳过确认":   c.SkipConfirm,
	}
}
